package org.hgg.workflow.core;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * @author Jarvis
 * @date 2023/12/27 23:30
 */
public final class DefaultDag<T, R> implements Dag<T, R> {

    private final Map<T, Node<T, R>> nodes = new HashMap<>();
    private Set<Node<T, R>> rootNodes;

    private Node<T, R> createNode(final T value) {
       /* if (nodes.containsKey(value)) {
            return nodes.get(value);
        }*/
        Node<T, R> trNode = nodes.computeIfAbsent(value, Node::new);
        //Node<T, R> node = new Node<>(value);
       // nodes.put(value, node);
        return trNode;
    }

    private void addEdges(final Node<T, R> firstNode, final Node<T, R> afterNode) {
        if (!firstNode.equals(afterNode)) {
            firstNode.getChildren().add(afterNode);
            afterNode.getParents().add(firstNode);
        }
    }


    @Override
    public void addDependency(T evalFirstNode, T evalLaterNode) {
        Node<T, R> firstNode = createNode(evalFirstNode);
        Node<T, R> afterNode = createNode(evalLaterNode);

        addEdges(firstNode, afterNode);
    }

    @Override
    public Node<T, R> getNode(T value) {
        return nodes.get(value);
    }

    @Override
    public Set<Node<T, R>> getRootNodes() {
        if (rootNodes == null) {
            rootNodes = new HashSet<>();
            for (Node<T, R> node : nodes.values()) {
                if (node.getInDegree() == 0) {
                    rootNodes.add(node);
                }
            }
        }
        return rootNodes;
    }
}
